package Dominio;

import java.io.Serializable;
import java.util.Collections;
import java.util.Vector;
import java.util.Vector;

/**
 ** Es la clase para representar los noticias clasificadas en la aplicacion, hereda de la clase Noticia
 * @author Sandra Crespo  
 * 
 */
public class NoticiaClasificada implements Serializable {

    private Vector<Tema> llTema;
    private Vector<Integer> llPalabra;
    private Vector<IdFrec> pf;
    private String titulo;
    private String path;
    private String seccion;

    /**
     * Crea una noticia clasificada vacia y se inicializan los vectores
     */
    public NoticiaClasificada(String t, String pathNot, String secc) {
        /*** {PRE:-}
         * {POST: se crea un tema con el Tema t}
         */
        path = pathNot;
        seccion =secc;
        llTema = new Vector<Tema>(0, 1);
        llPalabra = new Vector<Integer>(0, 1);
        pf = new Vector<IdFrec>(0, 1);
        titulo = t;
    }

    /**
     * Crea una noticia Calsificada con la fecha d, y con el cojunto de palabras y frecuencias vecFrec
     * @param d fecha de la noticia clasificada
     * @param vecFrec es un vector de PalFrec, donde cada PalFrec es una palabra y la frecuencia de la palabra en el documento
     */
    public NoticiaClasificada(Vector<IdFrec> vecFrec, String t, String pathNot, String secc) {
        /*** {PRE:vecFrec !=null}
         * {POST: se crea un tema con el titulo t, y se le asocian a la NoticiaClasificada las PalabrasParaAnadir del vector vecFrec}
         */
        path = pathNot;
        titulo = t;
        seccion =secc;
        llTema = new Vector<Tema>(0, 1);
        llPalabra = new Vector<Integer>(0, 1);
        pf = vecFrec;
        for (IdFrec palf : vecFrec) {
            llPalabra.add(palf.id);
        }
    }

    /**
     * Consulta los temas asociados a la noticia clasificada
     * @return devuelve un vector de punteros a los temas asociados de la noticia
     */
    public Vector<Tema> getTemas() {
        /*** {PRE:-}
         * {POST:devuelve un Vector de punteros a los Temas de la NoticiaClasificada. El Vector puede estar vacio}*/
        return llTema;
    }

     /**
     * Consulta el cuerpo de la noticia clasificada
     * @return devuelve un String con el cuerpo de la noticia
     */
    public String getPath() {
         /*** {PRE:-}
         * {POST:devuelve un String con el cuerpo de la noticia.}*/
        return path;
    }
    
    public String getSeccion(){
        return seccion;
    }

    /**
     * Consulta las palabras asociadas a la noticia clasificada
     * @return devuelve un vector de punteros a las palabras asociadas de la noticia
     */
    public Vector<Integer> getPalabras() {
        /*** {PRE:-}
         * {POST:devuelve un Vector de punteros a las PalabraParaAnadir de la NoticiaClasificada. El Vector puede estar vacio}*/
        return llPalabra;
    }

    /**
     * Consulta si la noticia esta asociada con un tema cuyo nombre viene dado por el string t
     * @param t nombre del tema que se desea consultar si está asociado o no.
     * @return  booleano que nos indica si existe un tema asociado a noticia cuyo nombre sea el string pasado.
     */
    public boolean esTema(String t) {
        /*** {PRE:-}
         * {POST:true: si hay una Tema asociado a Noticia Clasificada cuyo nombre sea t. false: si no hay ningun Tema asociado a Noticia Clasificada cuyo nombre sea t}*/
        for (Tema tma : llTema) {
            if (t.equals(tma.getNombre())) {
                return true;
            }
        }
        return false;
    }

    /**
     * Consulta si la noticia esta asociada con una palabra cuyo nombre viene dada por el string p
     * @param p nombre de la palabra que se desea consultar si está asociada o no.
     * @return  booleano que nos indica si existe una palabra cuyo nombre sea el string pasado.
     */
    public boolean esPalabra(int p) {
        /*** {PRE:-}
         * {POST:true: si hay una PalabraParaAnadir asociada a Noticia Clasificada cuyo nombre sea p. false: si no hay ninguna PalabraParaAnadir asociada a Noticia Clasificada cuyo nombre sea p}*/
        for (int pal : llPalabra) {
            if (pal==p) {
                return true;
            }
        }
        return false;
    }

    /**
     * anade un nuevo tema a la noticia clasificada
     * @param t Tema de la noticia que se desea anadir a la noticia
     * @return  booleano que nos indica si el tema se ha anadido bien o no.
     */
    public boolean addTema(Tema t) {
        /*** {PRE:t!=null y no hay ningun tema en la noticia con el mismo nombre que el tema t}
         * {POST:true: si el Tema t se ha anadido correctamente. false: si no se ha anadido correctamente}*/
        return llTema.add(t);
    }

    /**
     * anade una nueva Palabra a la noticia clasificada
     * @param p Palfrec que nos dice la palabra y la frecuencia de la palabra en el documento.
     * @return  booleano que nos indica si la palabra se ha anadido bien o no
     */
    public boolean addPalabra(IdFrec p) {
        /*** {PRE:p!=null, no hay ninguna palabra asociada a la noticia cuyo nombre sea el mismo que el de la palabra p.p}
         * {POST:true: si la PalabraParaAnadir y su frecuencia se han anadido correctamente. false: si no se han anadido correctamente}*/
        boolean b1 = llPalabra.add(p.id);
        boolean b2 = pf.add(p);
        return (b1 && b2);
    }

    /**
     * Consulta el numero de palabras asociadas a la noticia
     * @return  entero que nos dice el numero de palabras
     */
    public int sizePalabras() {
        /*** {PRE:-}
         * {POST: devuelve el numero de PalabrasParaAnadir asociadas con la NoticiaClasificada}*/
        return llPalabra.size();
    }

    /**
     * Consulta el numero de temas asociadas a la noticia
     * @return  entero que nos dice el numero de temas
     */
    public int sizeTemas() {
        /*** {PRE:-}
         * {POST: devuelve el numero de Temas asociadas con la NoticiaClasificada}*/
        return llTema.size();
    }

    /**
     * operacion que nos defuelve el df, que sirve xa calcular el vector centroide.
     * @return  vector de identificadores y el numero de frecuencias. está normalizado y ordenado por el id de las palabras.
     */
    public Vector<IdFrec> frecuencia(int N, DiccionarioPalabras dP) {
        /*** {PRE:-}
         * {POST:true:   vector de identificadores y el numero de frecuencias. está normalizado y ordenado por el id de las palabras.}*/
        Vector<IdFrec> dtf = new Vector<IdFrec>(0, 1);
        for (IdFrec palf : pf) {
            PalabraParaAnadir pa=new PalabraParaAnadir();
            pa=(PalabraParaAnadir) dP.consultarPalabra(palf.id);
            if (pa.getNApariciones(seccion) != 0) {
                if (N != 0) {
                    IdFrec iF = new IdFrec();
                    iF.id = pa.getId();
                    iF.frec = palf.frec * Math.log10(N / (double) pa.getNApariciones(seccion));
                    dtf.add(iF);
                }
            }
        }
        double aux = Math.sqrt(cuadrados(dtf));
        for (IdFrec idF : dtf) {
            if (aux != 0) {
                idF.frec = idF.frec / aux;
            } else {
                idF.frec = 0;
            }
        }
        Collections.sort(dtf);
        return dtf;
    }

    /**
     * Consulta el titulo de la noticia
     * @return  string que nos dice el titulo de palabras
     */
    public String getTitulo() {
        /*** {PRE:-}
         * {POST:devuelve el titulo de la NoticiaClasificada}*/
        return titulo;
    }
    
    

    // ************** OPERACIONES PRIVADAS
    private double cuadrados(Vector<IdFrec> idF) {
        double acum = 0;
        for (IdFrec idf : idF) {
            acum = acum + (idf.frec * idf.frec);
        }
        return acum;
    }
}
